using System;
using System.IO;
using EnvDTE;

using TextPoint = Microsoft.WowAddonStudio.Automation.TextPoint;

namespace Microsoft.WowAddonStudio.Tests.Common.Mocks
{
	/// <summary>
	/// Represents a text file open in the mock editor, such as the Visual Studio Code editor.
	/// </summary>
	public class MockTextDocument : TextDocument
	{
		private readonly string source;
		private readonly int lineCount;

		/// <summary>
		/// Initializes a new instance of the <see cref="MockTextDocument"/> class.
		/// </summary>
		/// <param name="dte">The DTE.</param>
		/// <param name="source">The source.</param>
		public MockTextDocument(DTE dte, string source)
		{
			DTE = dte;
			this.source = source;
			using (var reader = new StringReader(source))
			{
				while (reader.Peek() > -1)
				{
					lineCount++;
					reader.ReadLine();
				}
			}
		}

		#region TextDocument Members

		/// <summary>
		/// Removes all unnamed bookmarks in the text document.
		/// </summary>
		public void ClearBookmarks()
		{
			throw new NotImplementedException();
		}

		/// <summary>
		/// Indicates whether or not the indicated text was found in the text document and creates unnamed bookmarks wherever matching text is found.
		/// </summary>
		/// <param name="Pattern">Required. The text pattern to find.</param>
		/// <param name="vsFindOptionsValue">Optional. A <see cref="T:EnvDTE.vsFindOptions"/> constant that specifies the search text options.</param>
		/// <returns>
		/// A Boolean value true if the marked text was found in the text document, otherwise returns false.
		/// </returns>
		public bool MarkText(string Pattern, int vsFindOptionsValue)
		{
			throw new NotImplementedException();
		}

		/// <summary>
		/// Replaces matching text throughout an entire text document.
		/// </summary>
		/// <param name="Pattern">Required. The string to find.</param>
		/// <param name="Replace">Required. The text to replace each occurrence of <paramref name="Pattern"/>.</param>
		/// <param name="vsFindOptionsValue">Optional. A <see cref="T:EnvDTE.vsFindOptions"/> constant indicating the behavior of <see cref="M:EnvDTE.TextDocument.ReplacePattern(System.String,System.String,System.Int32,EnvDTE.TextRanges@)"/>, such as how to search, where to begin the search, whether to search forward or backward, and whether the search is case-sensitive.</param>
		/// <param name="Tags">Optional. A <see cref="T:EnvDTE.TextRanges"/> collection. If the matched text pattern is a regular expression and contains tagged subexpressions, then <paramref name="Tags"/> contains a collection of <see cref="T:EnvDTE.EditPoint"/> objects, one for each tagged subexpression.</param>
		/// <returns>A Boolean value.</returns>
		public bool ReplacePattern(string Pattern, string Replace, int vsFindOptionsValue, ref TextRanges Tags)
		{
			throw new NotImplementedException();
		}

		/// <summary>
		/// Creates an <see cref="T:EnvDTE.EditPoint"/> object at the specified location and returns it. The default location is the beginning of the document.
		/// </summary>
		/// <param name="TextPoint">Optional. A <see cref="T:EnvDTE.TextPoint"/> object to copy. If a value is supplied to <paramref name="TextPoint"/>, then the new point is at the same Line and <see cref="P:EnvDTE.EditPoint.LineCharOffset"/> as <paramref name="TextPoint"/>.</param>
		/// <returns>
		/// A <see cref="T:EnvDTE.EditPoint"/> object.
		/// </returns>
		public EditPoint CreateEditPoint(EnvDTE.TextPoint TextPoint)
		{
			return new MockEditPoint(DTE, source, TextPoint);
		}

		/// <summary>
		/// Microsoft Internal Use Only.
		/// </summary>
		/// <param name="FindText"></param>
		/// <param name="ReplaceText"></param>
		/// <param name="vsFindOptionsValue"></param>
		/// <returns>A Boolean value.</returns>
		public bool ReplaceText(string FindText, string ReplaceText, int vsFindOptionsValue)
		{
			throw new NotImplementedException();
		}

		/// <summary>
		/// Microsoft Internal Use Only.
		/// </summary>
		public void PrintOut()
		{
			throw new NotImplementedException();
		}

		/// <summary>
		/// Gets the top-level extensibility object.
		/// </summary>
		/// <value></value>
		/// <returns>A <see cref="T:EnvDTE.DTE"/> object.</returns>
		public DTE DTE { get; private set; }

		/// <summary>
		/// Gets the immediate parent object of a <see cref="T:EnvDTE.TextDocument"/> object.
		/// </summary>
		/// <value></value>
		/// <returns>A <see cref="T:EnvDTE.Document"/> object.</returns>
		public Document Parent
		{
			get { throw new NotImplementedException(); }
		}

		/// <summary>
		/// Gets an object representing the current selection on the <see cref="T:EnvDTE.TextDocument"/> object.
		/// </summary>
		/// <value></value>
		/// <returns>A <see cref="T:EnvDTE.TextSelection"/> object.</returns>
		public TextSelection Selection
		{
			get { throw new NotImplementedException(); }
		}

		/// <summary>
		/// Gets the <see cref="T:EnvDTE.TextPoint"/> object representing the beginning of the text document, or the first displayed character of the pane.
		/// </summary>
		/// <value></value>
		/// <returns>A <see cref="T:EnvDTE.TextPoint"/> object.</returns>
		public EnvDTE.TextPoint StartPoint
		{
            get { return new TextPoint(); }
		}

		/// <summary>
		/// Gets a <see cref="T:EnvDTE.TextPoint"/> object that is the location of the end of the document.
		/// </summary>
		/// <value></value>
		/// <returns>A <see cref="T:EnvDTE.TextPoint"/> object.</returns>
        public EnvDTE.TextPoint EndPoint
		{
			get { return new TextPoint(); }
		}

		/// <summary>
		/// Microsoft Internal Use Only.
		/// </summary>
		/// <value></value>
		/// <returns>A vsCMLanguage constant.</returns>
		public string Language
		{
			get { return "Lua"; }
			set { throw new NotImplementedException(); }
		}

		/// <summary>
		/// Microsoft Internal Use Only.
		/// </summary>
		/// <value></value>
		/// <returns>A <see cref="T:EnvDTE.CodeTypeRef"/> object.</returns>
		public string Type
		{
			get { throw new NotImplementedException(); }
		}

		/// <summary>
		/// Microsoft Internal Use Only.
		/// </summary>
		/// <value></value>
		/// <returns/>
		public int IndentSize
		{
			get { return 4; }
		}

		/// <summary>
		/// Microsoft Internal Use Only.
		/// </summary>
		/// <value></value>
		/// <returns/>
		public int TabSize
		{
			get { return 4; }
		}

		#endregion
	}
}